package com.aos.iot.socket.common.channel;

import com.aos.iot.socket.common.ack.AckCallback;
import com.aos.iot.socket.common.constant.ChannelMode;
import com.aos.iot.socket.common.message.Message;
import com.aos.iot.socket.common.protocol.IProtocol;
import io.netty.channel.Channel;
import io.netty.channel.socket.nio.NioDatagramChannel;

import java.net.SocketAddress;
import java.util.concurrent.Future;

public interface IChannel<M extends Message> {
    /**
     * 客户端标识
     */
    default String getClientId() {
        return getChannelId();
    }
    /**
     * 通道标识
     */
    String getChannelId();

    /**
     * 获取通达
     */
    Channel getChannel();

    /**
     * 获取通达通讯模式
     */
    default ChannelMode getChannelMode(){
        return getChannel() instanceof NioDatagramChannel ? ChannelMode.UDP : ChannelMode.TCP;
    }

    /**
     * 通道协议
     */
    IProtocol<M> getProtocol();

    /**
     * 客户端地址
     */
    SocketAddress getRemoteAddress();

    /**
     * 通道是否开启
     */
    boolean isChannelOpen();

    /**
     * 进入集群
     */
    void joinCluster(String clusterName);

    /**
     * 离开集群
     */
    void leaveCluster(String clusterName);

    /**
     * 关闭通道
     */
    void close();

    /**
     * 发送
     */
    void send(M message);

    /**
     * 发送
     */
    void send(M message, AckCallback<? extends Message> ackCallback);

    /**
     * 发送等待响应
     */
    <T extends Message> Future<T> sendCallback(M message, int timeout);

    /**
     * 发送并接收
     */
    <T extends Message> T sendAndReceive(M message, int timeout);

    /**
     * 集群内广播消息
     */
    void broadcast(String clusterName, M message);
}
